package com.googlecode.horncomb.web.extremetable.util;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.extremecomponents.table.context.Context;
import org.extremecomponents.table.context.HttpServletRequestContext;
import org.extremecomponents.table.core.Preferences;
import org.extremecomponents.table.core.PreferencesConstants;
import org.extremecomponents.table.core.Registry;
import org.extremecomponents.table.core.TableConstants;
import org.extremecomponents.table.core.TableModel;
import org.extremecomponents.table.core.TableModelImpl;
import org.extremecomponents.table.core.TableModelUtils;
import org.extremecomponents.table.core.TableProperties;
import org.extremecomponents.table.limit.Filter;
import org.extremecomponents.table.limit.FilterSet;
import org.extremecomponents.table.limit.LimitFactory;
import org.extremecomponents.table.limit.LimitRegistry;
import org.extremecomponents.table.limit.Sort;
import org.extremecomponents.table.limit.TableLimitFactory;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import com.googlecode.horncomb.bean.order.DefaultOrder;
import com.googlecode.horncomb.bean.order.Order;
import com.googlecode.horncomb.bean.order.DefaultOrderToken;
import com.googlecode.horncomb.bean.paged.DefaultPagedSetting;
import com.googlecode.horncomb.bean.paged.PagedSetting;

import javax.servlet.http.HttpServletRequest;

/**
 * 辅助ExtremeTable获取分页信息的Util
 */
public class ExtremeTableUtil {
	public static Map<String, PagedSetting> getPagedSettingMap(
			HttpServletRequest request) {
		Assert.notNull(request);
		Context context = new HttpServletRequestContext(request);
		String[] tabIds = request
				.getParameterValues(TableConstants.EXTREME_COMPONENTS_INSTANCE);
		Set<String> tableIdSet = new HashSet<String>();
		if (tabIds != null && tabIds.length > 0) {
			tableIdSet.addAll(Arrays.asList(tabIds));
		}
		return getPagedSetting(context, tableIdSet);
	}

	/**
	 * @param request
	 * @return
	 */
	public static PagedSetting getDefaultPagedSetting(HttpServletRequest request) {
		return getDefaultPagedSetting(request, getPagedSettingMap(request));
	}

	private static PagedSetting getDefaultPagedSetting(
			HttpServletRequest request,
			Map<String, PagedSetting> pagedSettingMap) {
		Assert.notNull(request);
		if (pagedSettingMap == null || pagedSettingMap.isEmpty()) {
			return null;
		} else {
			String[] tabIds = request
					.getParameterValues(TableConstants.EXTREME_COMPONENTS_INSTANCE);
			if (tabIds != null && tabIds.length > 0) {
				return pagedSettingMap.get(tabIds[0]);
			} else {
				return pagedSettingMap.values().iterator().next();
			}
		}
	}

	/**
	 * @param request
	 * @param tableIdSet
	 * @return
	 */
	public static Map<String, PagedSetting> getPagedSetting(
			HttpServletRequest request, Set<String> tableIdSet) {
		Context context = new HttpServletRequestContext(request);
		return getPagedSetting(context, tableIdSet);
	}

	private static Map<String, PagedSetting> getPagedSetting(Context context,
			Set<String> tableIdSet) {
		Assert.notNull(context);
		Map<String, PagedSetting> result = new HashMap<String, PagedSetting>();

		// build pageSize
		Preferences preferences = new TableProperties();
		preferences.init(null, TableModelUtils.getPreferencesLocation(context));
		String state = preferences
				.getPreference(PreferencesConstants.TABLE_STATE
						+ TableConstants.STATE_DEFAULT);
		String stateAttr = preferences
				.getPreference(PreferencesConstants.TABLE_STATE_ATTR);

		TableModel tabMod = new TableModelImpl(context);
		// default rows dispalyed
		String defaultRowsDisplayed = tabMod.getPreferences().getPreference(
				PreferencesConstants.TABLE_ROWS_DISPLAYED);

		if (tableIdSet == null) {
			tableIdSet = new HashSet<String>();
		}
		if (tableIdSet.isEmpty()) {
			tableIdSet.add(TableConstants.EXTREME_COMPONENTS);
		}

		for (String tableId : tableIdSet) {
			DefaultPagedSetting ps = new DefaultPagedSetting(tableId);

			String prefixWithTableId = tableId + "_";
			Registry registry = new LimitRegistry(context, tableId,
					prefixWithTableId, state, stateAttr);

			// current rows dispalyed, maybe null
			String currentRowsDisplayed = registry
					.getParameter(prefixWithTableId
							+ TableConstants.CURRENT_ROWS_DISPLAYED);
			// pageSize = limitFactory.getCurrentRowsDisplayed(totalRows,
			// defaultRowsDisplayed);

			int pageSize = Integer.parseInt(StringUtils
					.hasText(currentRowsDisplayed) ? currentRowsDisplayed
					: defaultRowsDisplayed);
			ps.setPageSize(pageSize);

			// page
			LimitFactory limitFactory = new TableLimitFactory(context, tableId);
			int page = limitFactory.getPage();
			ps.setPage(page);

			// build filter
			FilterSet filterSet = limitFactory.getFilterSet();
			if (filterSet != null && filterSet.getFilters() != null
					&& filterSet.getFilters().length > 0) {
				ExTabConditionSet cons = new ExTabConditionSet();
				for (Filter filter : filterSet.getFilters()) {
					cons.addConstraint(new ExTabConditionToken(filter
							.getProperty(), filter.getAlias(), filter
							.getValue()));
				}
				ps.setConditionSet(cons);
			}

			// build order
			Sort sort = limitFactory.getSort();
			Order order = null;
			if (sort != null && StringUtils.hasText(sort.getProperty())) {
				order = getOrder(sort);
			}
			ps.setOrder(order);

			result.put(ps.getName(), ps);
		}

		return result;
	}

	/**
	 * 将Limit中的排序信息转化为Order,升序/降序}
	 */
	private static Order getOrder(Sort sort) {
		Assert.notNull(sort);
		Order order = null;
		String fieldName = StringUtils.hasText(sort.getAlias()) ? sort
				.getAlias() : sort.getProperty();
		order = new DefaultOrder(new DefaultOrderToken(fieldName, "asc"
				.equalsIgnoreCase(sort.getSortOrder())));
		return order;
	}
}
